
local ReforgeSaver = CreateFrame("Frame", "ReforgeSaver", UIParent)
ReforgeSaver:SetScript("OnEvent", function(self, event, ...) self[event](self, ...) end)
ReforgeSaver.TimeSinceLastUpdate = 0
ReforgeSaver.UpdateInterval = 0
ReforgeSaver:SetScript("OnUpdate", function(self, elapsed) self:OnUpdate(self, elapsed) end)
ReforgeSaver:RegisterEvent("FORGE_MASTER_OPENED")
local RI = LibStub("LibReforgingInfo-1.0")
ReforgeSaverDB = ReforgeSaverDB or {}
local ReforgeQueue = {}
ReforgeSaverDB.Profiles = ReforgeSaverDB.Profiles or {}

local slots = {
	"HeadSlot",
	"NeckSlot",
	"ShoulderSlot",
	"BackSlot",
	"ChestSlot",
	"WristSlot",
	"HandsSlot",
	"WaistSlot",
	"LegsSlot",
	"FeetSlot",
	"Finger0Slot",
	"Finger1Slot",
	"Trinket0Slot",
	"Trinket1Slot",
	"MainHandSlot",
	"SecondaryHandSlot",
	}

local currentProfile = ""
local deleteProfile = ""
local Reforging = {}
local reforgeCost = 0

function ReforgeSaver:Print(msg)
	DEFAULT_CHAT_FRAME:AddMessage("|cff33ff99ReforgeSaver|r: " .. msg)
end

function ReforgeSaver:Save(name)
	if string.len(name) < 1 then
		UIErrorsFrame:AddMessage("You must enter a name", 1, 0, 0)
		return false
	end
	if not ReforgeSaverDB.Profiles then ReforgeSaverDB.Profiles = {} end
	ReforgeSaverDB.Profiles[name] = {}
	for k,v in ipairs(slots) do
		local item = GetInventoryItemLink("player", GetInventorySlotInfo(v))
		if item then
			ReforgeSaverDB.Profiles[name][v] = {}
			ReforgeSaverDB.Profiles[name][v]["Item"] = GetItemInfo(item)
			ReforgeSaverDB.Profiles[name][v]["ReforgeID"] = RI:GetReforgeID(item) or 0
		end
	end
	return true
end

function ReforgeSaver:ReforgeScan(test)
	test = test or false
	if currentProfile == "" then
		return
	end
	ReforgeQueue = {}
	for k,v in ipairs(slots) do
		local reforgeID, savedItem, savedReforgeID
		local item = GetInventoryItemLink("player", GetInventorySlotInfo(v))
		if item then
			itemName = GetItemInfo(item)
			reforgeID = RI:GetReforgeID(item) or 0
			if ReforgeSaverDB.Profiles[currentProfile][v] then
				savedItem, savedReforgeID = 
					ReforgeSaverDB.Profiles[currentProfile][v]["Item"],
					ReforgeSaverDB.Profiles[currentProfile][v]["ReforgeID"]
			end
			if (savedItem and itemName ~= savedItem) then
				Reforging[v] = nil
				if test == true then
					self:Print("|cffff0000WARNING|r: " .. savedItem .. " not equipped")
				end
			elseif reforgeID ~= savedReforgeID then
				if test == true and savedReforgeID ~= 0 then
					local _,_,_,_,_,_,_,_,_,_, vendorPrice = GetItemInfo(item)
					reforgeCost = reforgeCost + max(vendorPrice, 10000) -- 1g or vendor price if higher
				end
				ReforgeQueue["Slot"], ReforgeQueue["ReforgeID"] = v, savedReforgeID
				if test == false then
					self:Reforge()
					break
				end
			elseif Reforging[v] and test == false then
				Reforging[v] = nil
				
				if savedReforgeID == 0 then
					self:Print(item .. " restored")
				else
					local _, newStat = RI:GetReforgedStatNames(savedReforgeID)
					self:Print(item .. " reforged (" .. newStat .. ")")
				end
			end
		end

	end
	
	if test and not ReforgeQueue["ReforgeID"] then
		UIErrorsFrame:AddMessage("Nothing to reforge", 1, 0, 0)
	elseif test then
		StaticPopup_Show("REFORGESAVER_CONFIRM", currentProfile, self:GetReforgeCost())
	elseif not ReforgeQueue["ReforgeID"] then
		self.UpdateInterval = 0
		self:Print("Reforging Complete")
		CloseReforge()
	end
end

local function MakeFormat(G, S, C)
	local GSC = G.." "..S.." "..C
	local GS = G.." "..S
	local GC = G.." "..C
	local SC = S.." "..C
	local Z = C:format(0)
	return function(amount)
		if not amount then return "" end
		if amount <= 0 then return Z end
		if amount < 100 then return format(C, amount) end
		if amount < 10000 then
			local copper = amount % 100
			if copper > 0 then
				return format(SC, (amount-copper) / 100, copper)
			else
				return format(S, amount / 100)
			end
		else
			local copper = amount % 100
			if copper > 0 then
				local tmp = (amount-copper) / 100
				local silver = tmp % 100
				if silver > 0 then
					return format(GSC, (tmp-silver) / 100, silver, copper)
				else
					return format(GC, tmp / 100, copper)
				end
			else
				local tmp = amount / 100
				local silver = tmp % 100
				if silver > 0 then
					return format(GS, (tmp-silver) / 100, silver)
				else
					return format(G, tmp / 100)
				end
			end
		end
	end
end

local format = string.format
local coin = [[|cffffffff%%d|r|TInterface\AddOns\ReforgeSaver\textures\%s:0:0:1|t]]
local FormatMoneyCoin = MakeFormat(coin:format("gold"), coin:format("silver"), coin:format("copper"))
				   
function ReforgeSaver:GetReforgeCost()
	return FormatMoneyCoin(reforgeCost)

end

function ReforgeSaver:OnUpdate(self, elapsed)
	self.TimeSinceLastUpdate = self.TimeSinceLastUpdate + elapsed
	if (self.UpdateInterval > 0 and self.TimeSinceLastUpdate > self.UpdateInterval) then
		self:ReforgeScan()
		self.TimeSinceLastUpdate = 0
	end
end

function ReforgeSaver:Restore(name)
	if not ReforgeSaverDB.Profiles then ReforgeSaverDB.Profiles = {} end
	if not ReforgeSaverDB.Profiles[name] then
		return
	end
	
	if (ReforgingFrame == nil or ReforgingFrame:IsVisible() ~= 1) then
		UIErrorsFrame:AddMessage("Open the reforging frame", 1, 0, 0)
		return
	end
	self:Reset()
	self.UpdateInterval = 0
	reforgeCost = 0
	currentProfile = name
	if self:WaitToScan() then
		self:RegisterEvent("UNIT_INVENTORY_CHANGED")
	else
		self:ReforgeScan(true)
	end
end

function ReforgeSaver:Confirm()
	if reforgeCost > GetMoney("player") then
		UIErrorsFrame:AddMessage("Not enough gold to reforge", 1, 0, 0)
		return false
	else
		self:Print("Restoring profile \"" .. currentProfile .. "\"")
		self:ReforgeScan()
		return true
	end
end

StaticPopupDialogs["REFORGESAVER_CONFIRM"] = {
	text = "Reforging to \"%s\"\n%s",
	button1 = "Reforge",
	button2 = "Cancel",
	OnAccept = function() ReforgeSaver:Confirm() end,
	timeout = 0,
	whileDead = true,
	hideOnEscape = true,
	enterClicksFirstButton = true
}

StaticPopupDialogs["REFORGESAVER_DELETE"] = {
	text = "Delete profile \"%s\"?",
	button1 = "Delete",
	button2 = "Cancel",
	OnAccept = function()
			ReforgeSaverDB.Profiles[deleteProfile] = nil
			if (ReforgingFrame and ReforgingFrame:IsVisible() == 1) then
				UIDropDownMenu_Initialize(ReforgeSaver_Profiles, ReforgeSaver_Profiles_Init)
				UIDropDownMenu_SetSelectedID(ReforgeSaver_Profiles, 1)
				ReforgeSaver_Reforge:Disable()
				ReforgeSaver_SaveDelete:SetText("Save")
			end
				
		end,
	timeout = 0,
	whileDead = true,
	hideOnEscape = true,
	enterClicksFirstButton = true
}

StaticPopupDialogs["REFORGESAVER_SAVE"] = {
	text = "Enter a proflie name:",
	button1 = "Save",
	button2 = "Cancel",
	OnAccept = function(self)
			if (ReforgeSaver:Save(self.editBox:GetText()) == true and ReforgingFrame and ReforgingFrame:IsVisible() == 1) then
				UIDropDownMenu_Initialize(ReforgeSaver_Profiles, ReforgeSaver_Profiles_Init)
				UIDropDownMenu_SetSelectedName(ReforgeSaver_Profiles, self.editBox:GetText())
				ReforgeSaver_Reforge:Enable()
				ReforgeSaver_SaveDelete:SetText("Delete")
			end
		end,
	timeout = 0,
	whileDead = true,
	hideOnEscape = true,
	hasEditBox = true,
	enterClicksFirstButton = true
}

function ReforgeSaver:Reforge()
	
	if (ReforgingFrame == nil  or ReforgingFrame:IsVisible() ~= 1) then
		UIErrorsFrame:AddMessage("Open the reforging frame", 1, 0, 0)
		return
	end
		
	local item, ReforgeID =
		GetInventoryItemLink("player", GetInventorySlotInfo(ReforgeQueue["Slot"])),
		ReforgeQueue["ReforgeID"]
		
	if Reforging[ReforgeQueue["Slot"]] == nil then
		Reforging[ReforgeQueue["Slot"]] = true
		ClearCursor()
		PickupInventoryItem(GetInventorySlotInfo(ReforgeQueue["Slot"]))
		SetReforgeFromCursorItem()
		GameTooltip:Hide()
		ClearCursor()
	end
	
	local savedOldStat, savedNewStat = RI:GetReforgedStatNames(ReforgeQueue["ReforgeID"])
	local reforgeID
	
	if ReforgeQueue["ReforgeID"] == 0 then
		ReforgeItem(0)
	else
		for i=1, GetNumReforgeOptions() do
			oldStat, _, _, newStat = GetReforgeOptionInfo(i)
			if oldStat == savedOldStat and newStat == savedNewStat then
				ReforgeItem(i)
				break
			end
		end
	end
	
	self.UpdateInterval = max(select(4, GetNetStats())*2, 500)/1000
	
end

function ReforgeSaver:Reset()
		Reforging = {}
		ClearCursor()
		--ReforgingFrameItemButton:Click()
		ClearCursor()
		currentProfile = ""
end

function ReforgeSaver:Delete(name)
	deleteProfile = name
	if not ReforgeSaverDB.Profiles then ReforgeSaverDB.Profiles = {} end
	if not ReforgeSaverDB.Profiles[deleteProfile] then
		return
	end
	
	StaticPopup_Show("REFORGESAVER_DELETE", deleteProfile)
end

local profiles

function ReforgeSaver_Profiles_OnClick(self)
	UIDropDownMenu_SetSelectedID(ReforgeSaver_Profiles, self:GetID())
	if (UIDropDownMenu_GetSelectedID(ReforgeSaver_Profiles) == 1) then
		ReforgeSaver_Reforge:Disable()
		ReforgeSaver_SaveDelete:SetText("Save")
	else
		ReforgeSaver_Reforge:Enable()
		ReforgeSaver_SaveDelete:SetText("Delete")
	end
end
	
function ReforgeSaver_Profiles_Init(self, level)

	if ReforgeSaverDB.Format ~= 2 then
		ReforgeSaverDB.Format = 2
		ReforgeSaverDB.Profiles = {}
	end

	profiles = {}
	local info = UIDropDownMenu_CreateInfo()
	info = UIDropDownMenu_CreateInfo()
	info.text = "New profile..."
	info.value = "New"
	info.func = ReforgeSaver_Profiles_OnClick
	UIDropDownMenu_AddButton(info, level)
	tinsert(profiles, "New")
	for k,v in pairs(ReforgeSaverDB.Profiles) do
		info = UIDropDownMenu_CreateInfo()
		info.text = k
		info.value = k
		info.func = ReforgeSaver_Profiles_OnClick
		UIDropDownMenu_AddButton(info, level)
		tinsert(profiles, k)
	end
end
	
function ReforgeSaver:FORGE_MASTER_OPENED()

	if not ReforgeSaver_SaveDelete then
		CreateFrame("Button", "ReforgeSaver_SaveDelete", ReforgingFrame, "UIPanelButtonTemplate")
		ReforgeSaver_SaveDelete:SetFrameStrata("HIGH")
	end
	
	ReforgeSaver_SaveDelete:SetScript("OnClick", function(self, arg1)
			if (UIDropDownMenu_GetSelectedID(ReforgeSaver_Profiles) == 1) then
				StaticPopup_Show("REFORGESAVER_SAVE")
			else
				ReforgeSaver:Delete(profiles[UIDropDownMenu_GetSelectedID(ReforgeSaver_Profiles)])
			end
		end)
	ReforgeSaver_SaveDelete:SetHeight(26)
	ReforgeSaver_SaveDelete:SetText("Save")
	ReforgeSaver_SaveDelete:GetFontString():SetPoint("CENTER")
	ReforgeSaver_SaveDelete:SetPoint("TOPRIGHT", -19, -33)
	ReforgeSaver_SaveDelete:SetWidth(70)
	ReforgeSaver_SaveDelete:Raise()
	
	if not ReforgeSaver_Reforge then
		CreateFrame("Button", "ReforgeSaver_Reforge", ReforgingFrame, "UIPanelButtonTemplate")
		ReforgeSaver_Reforge:SetFrameStrata("HIGH")
	end
	
	ReforgeSaver_Reforge:SetScript("OnClick", function(self, arg1)
			ReforgeSaver:Restore(profiles[UIDropDownMenu_GetSelectedID(ReforgeSaver_Profiles)])
		end)
	ReforgeSaver_Reforge:SetHeight(26)
	ReforgeSaver_Reforge:SetText("Reforge")
	ReforgeSaver_Reforge:GetFontString():SetPoint("CENTER")
	ReforgeSaver_Reforge:SetPoint("TOPRIGHT", -93, -33)
	ReforgeSaver_Reforge:SetWidth(70)
	ReforgeSaver_Reforge:Raise()
	ReforgeSaver_Reforge:Disable()
	
	if not ReforgeSaver_Profiles then
		CreateFrame("Frame", "ReforgeSaver_Profiles", ReforgingFrame, "UIDropDownMenuTemplate")
		ReforgeSaver_Profiles:SetFrameStrata("HIGH")
	end

	ReforgeSaver_Profiles:ClearAllPoints()
	ReforgeSaver_Profiles:SetPoint("TOPLEFT", 37, -33)
	ReforgeSaver_Profiles:Show()

	UIDropDownMenu_Initialize(ReforgeSaver_Profiles, ReforgeSaver_Profiles_Init)
	UIDropDownMenu_SetWidth(ReforgeSaver_Profiles, 190);
	UIDropDownMenu_SetButtonWidth(ReforgeSaver_Profiles, 194)
	UIDropDownMenu_SetSelectedID(ReforgeSaver_Profiles, 1)
	UIDropDownMenu_JustifyText(ReforgeSaver_Profiles, "LEFT")

end

function ReforgeSaver:WaitToScan()
	if not GetEquipmentSetInfoByName(currentProfile) then return false end
	local infoArray = GetEquipmentSetLocations(currentProfile)
	for k,v in ipairs(infoArray) do
		player, _, bags = EquipmentManager_UnpackLocation(v)
		if player and bags == true then
			self:Print(format("Equipping set \"%s\"", currentProfile))
			UseEquipmentSet(currentProfile)
			return true
		end
	end
	return false
end

function ReforgeSaver:UNIT_INVENTORY_CHANGED(event)
	self:ReforgeScan(true)
	self:UnregisterEvent("UNIT_INVENTORY_CHANGED")
end
